package shiro.realm;

import org.apache.shiro.authc.AuthenticationException;
import org.apache.shiro.authc.AuthenticationInfo;
import org.apache.shiro.authc.AuthenticationToken;
import org.apache.shiro.authc.SimpleAuthenticationInfo;
import org.apache.shiro.authz.AuthorizationInfo;
import org.apache.shiro.authz.SimpleAuthorizationInfo;
import org.apache.shiro.realm.AuthorizingRealm;
import org.apache.shiro.subject.PrincipalCollection;
import org.apache.shiro.util.ByteSource;

// 自定义Realm
// 可参考SimpleAccountRealm
public class MyRealm extends AuthorizingRealm {

    // 授权==>其实是判断权限时调用如Subject.hasRole(...);Subject.hasAllRoles(...);等函数
    protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principalCollection) {
        System.out.println("==》执行MyRealm的doGetAuthorizationInfo() - AuthorizationInfo - 授权");

        //1.  获得主身份信息==>当前用户的用户名
        String primaryPrincipal = (String)principalCollection.getPrimaryPrincipal();
        System.out.println("当前用户身份信息(用户名):" + primaryPrincipal);

        //2.  根据获得的身份信息(用户名)从数据库获得当前用户的角色信息、权限信息等。。。
        // 数据库代码省略

        SimpleAuthorizationInfo simpleAuthorizationInfo = new SimpleAuthorizationInfo();
        //3. 将数据库获得的角色信息赋值给当前用户
        simpleAuthorizationInfo.addRole("admin"); // admin角色
        simpleAuthorizationInfo.addRole("user"); // user角色

        //4. 将数据库获得的权限赋值给给当前用户
        simpleAuthorizationInfo.addStringPermission("user:*:*"); //赋予对user模块的所有资源的所有操作的权限
        simpleAuthorizationInfo.addStringPermission("product:update:01"); //赋予对product模块01资源的更新操作的权限

        System.out.println("《==执行MyRealm的doGetAuthorizationInfo() - AuthorizationInfo - 授权");

        return simpleAuthorizationInfo;
    }

    // 认证
    protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken authenticationToken) throws AuthenticationException {
        System.out.println("MyRealm - AuthorizationInfo - 认证");

        // 从token中获取用户名
        String principal = (String)authenticationToken.getPrincipal();

        //实际开发中应当 根据身份信息使用jdbc mybatis查询相关数据库
        //在这里只做简单的演示
        //假设username,password是从数据库获得的信息
        String username = "wwj";
        String password = "7268f6d32ec8d6f4c305ae92395b00e8";

        if(username.equals(principal)){
            //参数1:返回数据库中正确的用户名
            //参数2:返回数据库中正确密码
            //参数3:随机盐
            //参数4:提供当前realm的名字 this.getName();
            SimpleAuthenticationInfo simpleAuthenticationInfo = new SimpleAuthenticationInfo(
                    principal,password, ByteSource.Util.bytes("@#$*&QU7O0!"),this.getName()
            );
            return simpleAuthenticationInfo;
        }
        return null;
    }
}